﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Net;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Linq.Expressions;

namespace Presentation.Web.Admin
{
    public static class MvcHtmlStringExtension
    {
        #region mvc html

        public static MvcHtmlString Include(this HtmlHelper htmlHelper, string url)
        {
            var path = HttpContext.Current.Request.PhysicalApplicationPath + url;
            return MvcHtmlString.Create(new WebClient().DownloadString(path));
        }

        public static MvcHtmlString GoBackPre(this HtmlHelper htmlHelper)
        {
            var str = "<a href='javascript:;' onclick='history.go(-1);'>返回上一页</a>";
            var res = MvcHtmlString.Create(str);
            return res;
        }

        public static MvcHtmlString GoBackPre(this HtmlHelper htmlHelper, string css, string text = "")
        {
            if (string.IsNullOrEmpty(text))
            {
                text = "返回上一页";
            }
            var str = "<a href='javascript:;' onclick='history.go(-1);' class ='" + css + "'>" + text + "</a>";
            var res = MvcHtmlString.Create(str);
            return res;
        }

        public static MvcHtmlString TreeView(this HtmlHelper htmlHelper, IEnumerable<Domain.Entity.RoleMenu> menu)
        {
            var sb = new System.Text.StringBuilder();
            if (menu != null && menu.Any())
            {
                var parent = menu.Where(e => e.ParentId == 0 && e.State == true).OrderBy(e => e.SortNum).ToList();
                if (parent.Any())
                {
                    for (int i = 0; i < parent.Count; i++)
                    {
                        sb.AppendLine("<h3 class = '" + parent[i].CssName + "'>" + "<span>" + parent[i].Name + "</span>" + "</h3>");
                        var temp = GetChildrenTreeView(menu, parent[i]);
                        if (!string.IsNullOrEmpty(temp))
                        {
                            sb.AppendLine("<ul class = 'toggle'>");
                            sb.AppendLine(temp);
                            sb.AppendLine("</ul>");
                        }
                    }
                }
            }
            return MvcHtmlString.Create(sb.ToString());
        }

        private static string GetChildrenTreeView(IEnumerable<Domain.Entity.RoleMenu> all, Domain.Entity.RoleMenu target)
        {
            var sb = new System.Text.StringBuilder();
            if (all != null && all.Any())
            {
                var child = all.Where(e => e.ParentId == target.Id && e.State == true).OrderBy(e => e.SortNum).ToList();
                if (child != null && child.Any())
                {
                    for (int i = 0; i < child.Count; i++)
                    {
                        var temp = GetChildrenTreeView(all, child[i]);
                        sb.AppendLine("<li class = '" + child[i].CssName + "'><a href='" + child[i].Url + "'>" + child[i].Name + "</a></li>");
                        if (!string.IsNullOrEmpty(temp))
                        {
                            sb.AppendLine("<ul class = 'toggle'>");
                            sb.AppendLine(temp);
                            sb.AppendLine("</ul>");
                        }
                    }
                }
            }
            return sb.ToString();
        }

        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, IEnumerable<Domain.Entity.RoleMenu> menu, object htmlAttributes)
        {
            var res = MvcHtmlString.Empty;
            if (menu != null && menu.Any())
            {
                var sb = new System.Text.StringBuilder();
                var parent = menu.Where(e => e.ParentId == 0 && e.State == true).OrderBy(e => e.SortNum).ToList();
                foreach (var item in parent)
                {
                    sb.AppendLine("<option value = '" + item.Id.ToString() + "'>" + item.Name + "</option>");
                    var children = GetChildrenDropDownList(menu, item, 1);
                    sb.AppendLine(children);
                }
                TagBuilder tagBuilder = new TagBuilder("select")
                {
                    InnerHtml = ((object)sb).ToString()
                };
                var attr = (IDictionary<string, object>)HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                if (attr != null && attr.Count > 0)
                {
                    tagBuilder.MergeAttributes<string, object>(attr);
                }
                res = MvcHtmlString.Create(tagBuilder.ToString());
            }
            return res;
        }

        private static string GetChildrenDropDownList(IEnumerable<Domain.Entity.RoleMenu> all, Domain.Entity.RoleMenu target, int span)
        {
            var sb = new System.Text.StringBuilder();
            if (all != null && all.Any())
            {
                var child = all.Where(e => e.ParentId == target.Id && e.State == true).OrderBy(e => e.SortNum).ToList();
                if (child != null && child.Any())
                {
                    var str = "";
                    for (int i = 0; i < span * 4; i++)
                    {
                        str += "-";
                    }
                    for (int i = 0; i < child.Count; i++)
                    {
                        if (all.Where(e => e.ParentId == child[i].Id).Any())
                        {
                            span += 1;
                        }
                        var temp = GetChildrenDropDownList(all, child[i], span);
                        sb.AppendLine("<option value = '" + child[i].Id + "'>" + str + child[i].Name + "</option>");
                        if (!string.IsNullOrEmpty(temp))
                        {
                            sb.AppendLine(temp);
                            span += 1;
                        }
                    }
                }
            }
            return sb.ToString();
        }

        public static bool HasUiPermission(this HtmlHelper htmlHelper, ControllerContext context, string actionName)
        {
            var res = false;
            var isPermission = System.Web.Configuration.WebConfigurationManager.AppSettings["IsStartPermission"];
            if (!string.IsNullOrEmpty(isPermission) && string.Compare(isPermission, "true", false) == 0)
            {
                if (context != null && !string.IsNullOrEmpty(actionName))
                {
                    var currentController = context.Controller.GetType();
                    //conrtoller有这个action
                    var hasAction = currentController.GetMethods().Where(d => d.IsPublic
                        && d.Name.ToLower() == actionName.ToLower()).Any();
                    if (hasAction)
                    {
                        //当前用户是否有这个权限
                        //这个方法不怎么稳定
                        //var cacheService = PreAdminEngine.Resolve<Infrastructure.Crosscutting.Caches.ICacheService>();
                        //var uiWorkContext = "webUiWorkContext-cache";
                        //if (cacheService != null)
                        //{
                        //    var workContext = cacheService.Get(uiWorkContext) as Infrastructure.Crosscutting.NetFramework.IWorkContext;
                        //    if (workContext != null)
                        //    {
                        //        res = workContext.HasCurrentPermission(currentController, actionName);
                        //    }
                        //    else
                        //    {
                        //        workContext = PreAdminEngine.Resolve<Infrastructure.Crosscutting.NetFramework.IWorkContext>();
                        //        if (workContext != null)
                        //        {
                        //            res = workContext.HasCurrentPermission(currentController, actionName);
                        //            cacheService.Insert(uiWorkContext, workContext, Infrastructure.Crosscutting.Comm.Service.ConstService.SessionExpires
                        //                , System.Web.Caching.CacheItemPriority.Default);
                        //        }
                        //    }
                        //}
                        //else
                        //{
                        //    var workContext = PreAdminEngine.Resolve<Infrastructure.Crosscutting.NetFramework.IWorkContext>();
                        //    if (workContext != null)
                        //    {
                        //        res = workContext.HasCurrentPermission(currentController, actionName);
                        //    }
                        //}
                        var workContext = PreAdminEngine.Resolve<Infrastructure.Crosscutting.NetFramework.IWorkContext>();
                        if (workContext != null)
                        {
                            res = workContext.HasCurrentPermission(currentController, actionName);
                        }
                    }
                }
            }
            else
            {
                res = true;
            }
            return res;
        }

        public static bool HasUiPermission(this HtmlHelper htmlHelper, string controllerName, string actionName)
        {
            var res = false;
            var isPermission = System.Web.Configuration.WebConfigurationManager.AppSettings["IsStartPermission"];
            if (!string.IsNullOrEmpty(isPermission) && string.Compare(isPermission, "true", false) == 0)
            {
                if (HttpContext.Current != null && HttpContext.Current.Session != null)
                {
                    var user = HttpContext.Current.Session[Infrastructure.Crosscutting.Comm.Service.ConstService.SessionNameCurrentUser]
                        as Domain.Entity.User;
                    if (user != null)
                    {
                        if (!string.IsNullOrEmpty(controllerName))
                        {
                            if (controllerName.ToLower().EndsWith("controller"))
                            {
                                controllerName = controllerName.Replace("Controller", "");
                                controllerName = controllerName.Replace("controller", "");
                            }
                            controllerName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Controllers." + controllerName + "Controller";
                            var userRoleService = PreAdminEngine.Resolve<Infrastructure.Crosscutting.Authorize.IUserRoleService>();
                            var rolePremissionService = PreAdminEngine.Resolve<Infrastructure.Crosscutting.Authorize.IMvcRolePermissionService>();
                            var controllerService = PreAdminEngine.Resolve<Infrastructure.Crosscutting.Authorize.IMvcControllerService>();
                            var actionService = PreAdminEngine.Resolve<Infrastructure.Crosscutting.Authorize.IMvcActionService>();
                            res = (from userRole in userRoleService.GetList()
                                   join permission in rolePremissionService.GetList() on userRole.RoleId equals permission.RoleId
                                   join action in actionService.GetList() on permission.ActionId equals action.Id
                                   join controller in controllerService.GetList() on action.ControllerId equals controller.Id
                                   where controller.AssemblyFullName == controllerName && action.Name.ToLower() == actionName.ToLower()
                                   select action
                                   ).Any();
                        }
                    }
                }
            }
            else
            {
                res = true;
            }
            return res;
        }

        #endregion
    }

    public static class ListExtensionService
    {
        #region ienumerable ilist

        public static IList<int> ToIntList(this IList<string> source)
        {
            var target = new List<int>();
            if (source != null)
            {
                foreach (var item in source)
                {
                    var id = -1;
                    int.TryParse(item, out id);
                    if (id > 0)
                    {
                        target.Add(id);
                    }
                }
            }
            return target;
        }

        public static bool IsEmpty<T>(this IEnumerable<T> source)
        {
            return !source.Any();
        }

        public static bool IsNotEmpty<T>(this IEnumerable<T> source)
        {
            return source.Any();
        }

        #endregion

        #region func

        public static Expression<Func<T, bool>> True<T>()
        {
            return f => true;
        }

        public static Expression<Func<T, bool>> False<T>()
        {
            return f => false;
        }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.And(expr1.Body, invokedExpr), expr1.Parameters);
        }

        #endregion
    }

    public static class PreAdminConfigSettingService
    {
        public static string PicSavePath
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["PicSavePath"];
                return res;
            }
        }

        public static string ExcelSavePath
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["ExcelSavePath"];
                return res;
            }
        }

        public static string VideoSavePath
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["VideoSavePath"];
                return res;
            }
        }

        public static string WaterImagePath
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["WaterImagePath"];
                return res;
            }
        }

        public static string WaterTextName
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["WaterTextName"];
                return res;
            }
        }

        public static string WaterImageNewFileNamePreName
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["WaterImageNewFileNamePreName"];
                return res;
            }
        }

        public static string WaterTextNewFileNamePreName
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["WaterTextNewFileNamePreName"];
                return res;
            }
        }

        public static string IsWaterImage
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["IsWaterImage"];
                return res;
            }
        }

        public static string IsWaterText
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["IsWaterText"];
                return res;
            }
        }

        public static string IsThumbWaterImage
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["IsThumbWaterImage"];
                return res;
            }
        }

        public static string IsThumbWaterText
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["IsThumbWaterText"];
                return res;
            }
        }

        public static string IsCheckOpenUser
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["IsCheckOperUser"];
                return res;
            }
        }

        public static string PushKeyFilePath
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["PushKeyFilePath"];
                return res;
            }
        }

        public static string PushKeyFilePwd
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["PushKeyFilePwd"];
                return res;
            }
        }

        public static bool IsPushSandbox
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["IsPushSandbox"];
                var b = false;
                if (!string.IsNullOrEmpty(res) && string.Compare(res, "true", false) == 0)
                {
                    b = true;
                }
                return b;
            }
        }

        public static int AutoPushTimerNum
        {
            get
            {
                var res = System.Configuration.ConfigurationManager.AppSettings["AutoPushTimerNum"];
                var t = 10;
                int.TryParse(res, out t);
                if (t < 10)
                {
                    t = 10;
                }
                return t;
            }
        }

        public static bool IsAddAutoPushTextLog
        {
            get
            {
                var b = false;
                var res = System.Configuration.ConfigurationManager.AppSettings["IsAddAutoPushTextLog"];
                if (!string.IsNullOrEmpty(res) && string.Compare(res, "true", false) == 0)
                {
                    b = true;
                }
                return b;
            }
        }

        public static bool IsAutoPush
        {
            get
            {
                var b = false;
                var res = System.Configuration.ConfigurationManager.AppSettings["IsAutoPush"];
                if (!string.IsNullOrEmpty(res) && string.Compare(res, "true", false) == 0)
                {
                    b = true;
                }
                return b;
            }
        }
    }
}